<template>
  <div class="drow-container" :style="{ width: `${width}px`, height: `${height}px` }" v-loading="mapLoading"
    element-loading-text="平面图加载中..." element-loading-spinner="el-icon-loading"
    element-loading-background="rgba(0, 0, 0, 0.99)">
    <div class="top">
      <titleCom :name="'工具栏'" :show-title="false">
        <div slot="tip">
          <i class="iconfont icon-box" />
        </div>
        <div class="top-container">
          <miniCom :name="'图层显示'">
            <div slot="content">
              <layerCom ref="layerCom" :width="'170px'" @giveCheckedlayers="giveCheckedlayers"
                :layerArr="['模型名称', '模型朝向', '模型框架']" />
            </div>
          </miniCom>
          <miniCom :name="'模块显示'">
            <div slot="content">
              <layerCom ref="layerCom2" :width="'170px'" @giveCheckedlayers="giveCheckedlayers2"
                :layerArr="['业务列表', '标尺', '模型列表']" />
            </div>
          </miniCom>
          <miniCom :name="'模块参数'">
            <div slot="content">
              <modelparamsCom ref="modelparamsCom" @updatemodelParams="updatemodelParams" />
            </div>
          </miniCom>
          <miniCom :name="'常用按钮'">
            <div slot="content">
              <fastenerCom @resetView="resetView" />
            </div>
          </miniCom>
          <miniCom :name="''" style="margin-left: auto; margin-right: 10px">
            <div slot="content">
              <topButton @handlePointList="handlePointList" @handleReset="handleReset" @handleSave="handleSave"
                @handleCancel="handleCancel" />
            </div>
          </miniCom>
        </div>
      </titleCom>
    </div>
    <draggableCom v-show="show1" :class="['business', show1 ? '' : 'hidden']"
      :childStyle="'width: ' + modelParams[0].val[0].val + 'px; height: 40px;'">
      <div slot="content">
        <titleCom :name="'业务列表'" :empty="false" :emptyheight="modelParams[0].val[1].val + 'px'"
          :emptywidth="modelParams[0].val[0].val + 'px'" ref="titleCom1">
          <div slot="tip">
            <i class="iconfont icon-yewu" />
          </div>
          <businessList :img-arr="yewuimgArr" :position-type="positionType" :listHeight="modelParams[0].val[1].val"
            :listWidth="modelParams[0].val[0].val" :selected-position="selectedPosition"
            :filtered-position-msg-arr="filteredPositionMsgArr" @handleSelectValue="handleSelectValue"
            @handleSelectPosition="handleSelectPosition" @handleFiltrate="handleFiltrate" />
        </titleCom>
      </div>
    </draggableCom>
    <draggableCom v-show="show2" :class="['model-area', show2 ? '' : 'hidden']"
      :childStyle="'width: ' + modelParams[1].val[0].val + 'px; height: 40px;'">
      <div slot="content">
        <titleCom :name="'模型列表'" :empty="false" :emptyheight="modelParams[1].val[1].val + 'px'"
          :emptywidth="modelParams[1].val[0].val + 'px'" ref="titleCom2">
          <div slot="tip">
            <i class="iconfont icon-model" />
          </div>
          <imageList :listHeight="modelParams[1].val[1].val" :listWidth="modelParams[1].val[0].val"
            :position-type="positionType" :img-arr="imgArr" :chose-img="choseImg" @handleSelectImage="handleSelectImage"
            @handleFindImgItems="handleFindImgItems" />
        </titleCom>
      </div>
    </draggableCom>
    <div class="hover" v-if="hoverObject && Object.keys(hoverObject).length > 0">
      <hoverTarget :hoverObject="hoverObject" />
    </div>
    <div class="mid" :style="{ height: `${midHeight}px` }">
      <div class="canvas-container">
        <div class="canvas-area">
          <rulerCom :canvasWidth="canvasWidth" :canvasHeight="canvasHeight" :scaleFactor="scaleFactor"
            :showRuler="showRuler" />
          <canvas id="imageEffectCanvas" />
        </div>
      </div>
    </div>
    <draggableCom v-show="show3" :class="['chose-target', show3 ? '' : 'hidden']" :style="'z-index: ' + zIndex1"
      :childStyle="'width: 400px; height: 40px;'">
      <div slot="content">
        <titleCom :name="'点位信息'" :empty="allObjects.length === 0 ? true : false" :emptyheight="targetHeight + 'px'"
          ref="titleCom3">
          <div slot="tip">
            <i class="iconfont icon-target" />
          </div>
          <targetChose :all-objects="allObjects" :position-type="positionType" :img-arr="imgArr"
            :targetHeight="targetHeight" @handleSelectItemValue="handleSelectItemValue"
            @handleSelectItemValue2="handleSelectItemValue2" @updateObjText="updateObjText"
            @updateObjProperty="updateObjProperty" @deleteObject="deleteObject"
            @updateAllObjects="updateAllObjectsconfigForm" ref="targetChose" />
        </titleCom>
      </div>
    </draggableCom>
    <popCom v-if="!mapLoading" :visible.sync="showpopCom" :title="'地图点位列表'" :widthNumber="tableWidth">
      <div slot="content">
        <positionTable :all-objects="allObjects" :position-type="positionType" :img-arr="listimgArr"
          @handleSelectItemValue="handleSelectItemValue" @handleSelectItemValue2="handleSelectItemValue2"
          @updateObjText="updateObjText" @updateObjProperty="updateObjProperty" @deleteObject="deleteObject" />
      </div>
      <div slot="footer">
        <el-button type="primary" @click="closePop">关 闭</el-button>
      </div>
    </popCom>
    <MessageBox ref="messageBox" :title="messageBoxtitle" :buttons="customButtons" @close="onmsgClose" />
    <loadCom :loadTarget="saveLoad" :tips="'保存中'" />
  </div>
</template>

<script>
import "@/assets/css/iconfont.css";
import { ConfigType } from "@/utils/config-type";
import { initModules } from "./mixins/index";
// import { fabric } from "fabric";
// import { initAligningGuidelines } from "@/utils/aligning_guidelines_plus_ultimate.js"; // 引入辅助线方法
import titleCom from "@/components/Title/index.vue";
import miniCom from "@/components/Title/mini.vue";
import lampCom from "@/components/Lamp/index.vue";
import popCom from "@/components/DialogPop/index.vue";
import MessageBox from "@/components/MessageBox/index.vue";
import loadCom from "@/components/Load/index.vue";
import draggableCom from "@/components/Draggable/index.vue";
import layerCom from "./components/layer-chose.vue";
import fastenerCom from "./components/fastener.vue";
import targetChose from "./components/target-chose.vue";
// import positionList from "./components/position-list.vue";
import businessList from "./components/business-list.vue";
import imageList from "./components/image-list.vue";
import stepsCom from "./components/steps.vue";
import topButton from "./components/top-button.vue";
import positionTable from "./components/position-table.vue";
import hoverTarget from "./components/hover-target.vue";
import rulerCom from "./components/ruler-com.vue";
import modelparamsCom from "./components/model-params.vue";
export default {
  components: {
    titleCom,
    miniCom,
    layerCom,
    fastenerCom,
    lampCom,
    // positionList,
    targetChose,
    businessList,
    imageList,
    stepsCom,
    topButton,
    popCom,
    positionTable,
    MessageBox,
    draggableCom,
    hoverTarget,
    loadCom,
    rulerCom,
    modelparamsCom,
  },
  data() {
    const configData = ConfigType;
    return {
      width: window.innerWidth,
      height: window.innerHeight,
      canvasWidth: 0,
      canvasHeight: 0,
      midHeight: 0,
      listHeight: 0,
      targetHeight: 0,
      tableWidth: 0,
      positionHeight: 0,
      ConfigType: configData,
      mapLoading: true,
      buildingId: null,
      mapId: null,
      ossId: null,
      canvas: null,
      dig: 3, // 保留几位小数
      // backimg: require("@/assets/backimg.png"), // 底图地址
      backimg: "", // 底图地址
      backgroundImage: null, // 底图对象
      initialZoom: 1, // 保存初始缩放比例
      maxZoom: 20, // 最大缩放比例
      minZoom: 0.5, // 最小缩放比例
      isDragging: false, // 是否正在拖动
      lastPosX: 0, // 拖拽的点位x坐标
      lastPosY: 0, // 拖拽的点位y坐标
      yewuimgArr: [],
      imgArr: [],
      listimgArr: [],
      selectedImg: null, // 当前选中的图片对象
      choseImg: {}, // 当前选中的图片信息
      choseObj: null, // 最后选择的对象信息
      allObjects: [], // 保存所有放置的图片加文字的对象信息
      checkedlayers: [], // 保存当前显示的图层
      checkedmodels: [], // 保存当前显示的模块
      isTextVisible: true, // 控制文字是否显示
      isArrowVisible: true, // 控制箭头是否显示
      isBorderVisible: true, // 控制边框是否显示
      positionMsgArr: [], // 业务列表
      filteredPositionMsgArr: [], // 过滤后显示的业务列表
      selectValue: "", // 业务列表下拉选中的值
      filtrate: {}, // 业务列表过滤条件
      selectedPosition: null, // 选中的业务信息
      positionImg: null, // 业务列表下拉选中的图片
      floorPoint: [], // 楼层的点位信息
      rate: 1, // 标准比例
      positionType: [],
      isChild: false,
      showpopCom: false, // 弹窗显示状态
      customButtons: [],
      messageBoxtitle: "",
      show1: true,
      show2: true,
      show3: false,
      show4: true,
      isRendering: false, // 渲染状态锁
      lastRenderTime: 0, // 上次渲染时间
      renderThrottle: 50, // 渲染节流时间(ms)
      // originalBackgroundWidth: 0,
      // originalBackgroundHeight: 0,
      borderAndpadding: 40, // 20px
      hoverObject: null, // 鼠标悬停的对象
      saveLoad: false,
      scaleFactor: 1,
      showRuler: true,
      zIndex1: 2,
      zIndex2: 3,
      modelParams: [
        {
          name: "业务",
          key: 1,
          val: [
            {
              name: "宽度",
              key: "w",
              val: 400,
            },
            {
              name: "高度",
              key: "h",
              val: 0,
            },
          ],
        },
        {
          name: "模型",
          key: 2,
          val: [
            {
              name: "宽度",
              key: "w",
              val: 400,
            },
            {
              name: "高度",
              key: "h",
              val: 0,
            },
          ],
        },
      ],
      vrPanoramaArr: []
    };
  },
  // 监听checkedlayers的变化
  watch: {
    checkedlayers(newVal) {
      // 检查是否包含“模型名称”、“模型朝向”
      this.isTextVisible = newVal.includes("模型名称");
      this.isArrowVisible = newVal.includes("模型朝向");
      this.isBorderVisible = newVal.includes("模型框架");
      // 动态设置所有图层对象的可见性
      this.allObjects.forEach((obj) => {
        if (obj.textObject) {
          obj.textObject.visible = this.isTextVisible;
        }
        if (obj.arrowObject) {
          obj.arrowObject.visible = this.isArrowVisible;
        }
        if (obj.borderObject) {
          obj.borderObject.visible = this.isBorderVisible;
        }
      });
      this.canvas.requestRenderAll();
    },
    checkedmodels(newVal) {
      let a = newVal.includes("业务列表");
      let b = newVal.includes("模型列表");
      // let c = newVal.includes("选中点位");
      // let d = newVal.includes("点位列表");
      let d = newVal.includes("标尺");
      this.show1 = a;
      this.show2 = b;
      this.showRuler = d;
      // this.show3 = c;
      // this.show4 = d;
    },
  },
  created() {
    this.methods = initModules(this);
  },
  mounted() {
    this.initHeight();
    this.ossId = this.$route.query.ossId;
    this.mapId = this.$route.query.mapId;
    this.buildingId = this.$route.query.buildingId;
    this.isChild = this.$route.query.isChild == 1 ? true : false;
    this.loadLowLarDa();
    this.requestpositionMsg();
    window.addEventListener("resize", this.handleResize);
  },
  beforeDestroy() {
    this.canvasRemoveEventListeners();
    window.removeEventListener("resize", this.handleResize);
  },
  methods: {
    // 使用展开运算符混入方法
    ...Object.keys(initModules(this)).reduce((acc, key) => {
      acc[key] = function (...args) {
        return this.methods[key].apply(this, args);
      };
      return acc;
    }, {}),
    // 定义重置 z-index 的方法
    resetDraggableZIndex() {
      this.$nextTick(() => {
        const draggableComs = document.querySelectorAll(".draggable-container");
        draggableComs.forEach((com) => {
          com.style.zIndex = this.zIndex1;
        });
      });
    },
    /* ..........页面高度初始化.......... */
    initHeight() {
      this.width = window.innerWidth;
      this.canvasWidth = this.width - 80;
      this.tableWidth = this.width - 200;
      this.height = window.innerHeight;
      this.midHeight = this.height - 60;
      this.canvasHeight = this.midHeight - 30;
      this.listHeight = this.midHeight / 2 - 65;
      this.modelParams[0].val[1].val = this.listHeight;
      this.modelParams[1].val[1].val = this.listHeight;
      this.targetHeight = this.midHeight - 85;
      this.positionHeight = this.midHeight - 710;
      this.$refs.modelparamsCom.setmodelParams(this.modelParams);
    },
    /* ..........执行天梯.......... */
    async loadLowLarDa() {
      try {
        this.initData();
        const [result1, result2, result3, result7] = await Promise.all([
          this.requestGetFloorImg(),
          this.requestgetModel(),
          this.requestEnums(),
          this.requestpanoramaList()
        ]);
        if (!result1 || !result2 || !result3 || !result7) throw new Error("信息请求错误");
        const result4 = await this.canvasInitImageEffectCanvas(
          result1,
          result2,
          result3,
          result7
        );
        if (!result4) throw new Error("底图加载错误");
        const floorPoint = await this.requestFloorPoint();
        if (floorPoint === false) throw new Error("楼层点位获取失败");
        const result5 = await this.canvasInitPositionInfo(floorPoint);
        if (!result5) throw new Error("楼层点位绘制错误");
        const result6 = await this.canvasRender(result5);
        if (!result6) throw new Error("画布渲染错误");
      } catch (error) {
        this.mapLoading = true;
        this.$message.error(`${error.message}，请稍后刷新再试！`);
      } finally {
      }
    },
    initData() {
      // 清理现有画布
      if (this.canvas) {
        this.canvas.clear();
        this.canvas.dispose();
      }
      this.backimg = "";
      this.backgroundImage = null;
      this.initialZoom = 1;
      this.isDragging = false;
      this.lastPosX = 0;
      this.lastPosY = 0;
      this.imgArr = [];
      this.selectedImg = null;
      this.choseImg = {};
      this.choseObj = null;
      this.allObjects = [];
      this.positionMsgArr = [];
      this.filteredPositionMsgArr = [];
      this.selectValue = "";
      this.selectedPosition = null;
      this.positionImg = null;
      this.floorPoint = [];
      this.positionType = [];
      this.mapLoading = true;
      this.show3 = false;
    },
  },
};
</script>

<style lang="scss" scoped>
@import "@/styles/index.scss";

.drow-container {
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;

  .el-icon-close {
    cursor: pointer;
    color: #ff4d4f;
    font-size: 18px;
    font-weight: bold;
  }

  .top {
    width: 100%;
    height: 50px;
    margin-bottom: 10px;

    .top-container {
      width: 100%;
      height: 50px;
      display: flex;
      align-items: center;
    }
  }

  .business {
    left: 40px;
    top: 72px;
    z-index: 2;
  }

  .model-area {
    left: 40px;
    bottom: 20px;
    z-index: 2;
  }

  .hover {
    position: absolute;
    left: 45%;
    top: 50px;
    z-index: 2;
  }

  .mid {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;

    .canvas-container {
      height: 100%;

      .canvas-area {
        border-radius: 10px;
        padding: 10px;
        border: 2px solid rgb(235, 238, 245);
        box-shadow: rgba(0, 0, 0, 0.1) 0px 2px 12px 0px;

        #imageEffectCanvas {
          transform: translateZ(0); // GPU该你上场了
          will-change: transform;
        }
      }
    }
  }

  .chose-target {
    right: 40px;
    top: 72px;
    z-index: 2;
  }

  .hidden {
    display: none;
  }
}

// /* 小屏幕 */
// @media screen and (min-width: 0px) and (max-width: 1366px) {
//   .left {
//     display: none;
//   }
//   .right {
//     display: none;
//   }
// }
// /*  正常屏幕 */
// @media screen and (min-width: 1367px) {
//   .left {
//     width: 180px;
//     height: 100%;
//     display: flex;
//     flex-direction: column;
//     justify-content: space-between;
//   }
//   .right {
//     width: 380px;
//     height: 100%;
//     display: flex;
//     flex-direction: column;
//     align-items: center;
//     justify-content: space-between;
//   }
// }</style>
